package com.aruba.linemoveview.library;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Created by aruba on 2018/7/31.
 */

public class LineMoveView extends View {
    private float width, height;
    private Paint mPaint = new Paint();
    private Path mLinePath;
    private LinearGradient linearGradient;

    private PathMeasure mPathMeasure;
    private float[] pos;
    private float[] tan;

    private int padding = 100;
    //两边圆的半径
    private int radius = 15;
    private float leftCirclePosX, leftCirclePosY, rightCirclePosX, rightCirclePosY;
    //线宽
    private int lineWidth = 8;

    //动画执行值
    private float currentValue = 0;
    private ValueAnimator mAnimator;

    //水波
    private Paint mWhellPaint = new Paint();
    //circle
    private Paint mCircleLeftPaint = new Paint();
    private Paint mCircleRightPaint = new Paint();

    public LineMoveView(Context context) {
        this(context, null);
    }

    public LineMoveView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LineMoveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        //初始化宽和高,paint等
        width = MeasureSpec.getSize(widthMeasureSpec);
        height = MeasureSpec.getSize(heightMeasureSpec);
        init();
    }

    private void init() {
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(lineWidth);
        mPaint.setColor(Color.parseColor("#00fffc"));
        mPaint.setStyle(Paint.Style.STROKE);

        mCircleLeftPaint.setAntiAlias(true);
        mCircleLeftPaint.setColor(mPaint.getColor());
        mCircleLeftPaint.setStyle(Paint.Style.FILL);

        mCircleRightPaint.setAntiAlias(true);
        mCircleRightPaint.setColor(Color.parseColor("#6558db"));
        mCircleRightPaint.setStyle(Paint.Style.FILL);

        mWhellPaint.setAntiAlias(true);
        mWhellPaint.setColor(Color.parseColor("#00fffc"));
        mWhellPaint.setStyle(Paint.Style.FILL);

        mLinePath = new Path();
        leftCirclePosX = padding + radius;
        leftCirclePosY = height - radius - padding;
        rightCirclePosX = width - padding - radius;
        rightCirclePosY = padding + radius;

        linearGradient = new LinearGradient(leftCirclePosX, leftCirclePosY, rightCirclePosX, rightCirclePosY
                , new int[]{mPaint.getColor(), mCircleRightPaint.getColor()}
                , new float[]{0, 0.3f}
                , LinearGradient.TileMode.CLAMP);
        mPaint.setShader(linearGradient);

        //线的宽度
        float lineWidth = rightCirclePosX - leftCirclePosX;
        //线的高度
        float lineHeight = leftCirclePosY - rightCirclePosY;

        mLinePath.moveTo(leftCirclePosX, leftCirclePosY);
        //第一根横线
        mLinePath.lineTo(leftCirclePosX + lineWidth / 2.5f, leftCirclePosY);
        //第一根竖线
        mLinePath.lineTo(leftCirclePosX + lineWidth / 2.5f, leftCirclePosY - lineHeight / 2.0f);
        //第二根横线
        mLinePath.lineTo(leftCirclePosX + lineWidth * 2 / 2.5f, leftCirclePosY - lineHeight / 2.0f);
        //第二根竖线
        mLinePath.lineTo(leftCirclePosX + lineWidth * 2 / 2.5f, rightCirclePosY);
        //第三根竖线
        mLinePath.lineTo(rightCirclePosX, rightCirclePosY);

        mPathMeasure = new PathMeasure();
        mPathMeasure.setPath(mLinePath, false);
        pos = new float[2];
        tan = new float[2];
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        mPathMeasure.getPosTan(mPathMeasure.getLength() * currentValue, pos, tan);
        canvas.save();
        canvas.drawPath(mLinePath, mPaint);
        canvas.drawCircle(leftCirclePosX, leftCirclePosY, radius, mCircleLeftPaint);
        canvas.drawCircle(rightCirclePosX, rightCirclePosY, radius, mCircleRightPaint);
        canvas.restore();

        Iterator<Circle> iterator = mCircleList.iterator();
        while (iterator.hasNext()) {
            Circle circle = iterator.next();
            if (System.currentTimeMillis() - circle.mCreateTime < mDuration) {
                mWhellPaint.setAlpha(circle.getAlpha());
                canvas.drawCircle(pos[0], pos[1], circle.getCurrentRadius(), mWhellPaint);
            } else {
                iterator.remove();
            }
        }
        if (mCircleList.size() > 0) {
            postInvalidateDelayed(10);
        }
    }

    public void startAnime() {
        if (mAnimator != null) {
            mAnimator.cancel();
            mAnimator = null;
        }

        mAnimator = ValueAnimator.ofFloat(0, 1);
        mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                currentValue = (float) valueAnimator.getAnimatedValue();
                invalidate();
            }
        });
        mAnimator.setInterpolator(new LinearInterpolator());
        mAnimator.setDuration(4800);
        mAnimator.setRepeatCount(ValueAnimator.INFINITE);
        mAnimator.setRepeatMode(ValueAnimator.REVERSE);
        mAnimator.start();

        start();
    }

    private float mInitialRadius;   // 初始波纹半径
    private float mMaxRadiusRate = 0.85f;   // 如果没有设置mMaxRadius，可mMaxRadius = 最小长度 * mMaxRadiusRate;
    private float mMaxRadius = 80;   // 最大波纹半径
    private long mDuration = 1000; // 一个波纹从创建到消失的持续时间
    private int mSpeed = 250;   // 波纹的创建速度，每500ms创建一个

    private List<Circle> mCircleList = new ArrayList<Circle>();
    private boolean mIsRunning;

    private Interpolator mInterpolator = new LinearInterpolator();

    private boolean mMaxRadiusSet;

    private long mLastCreateTime;

    private Runnable mCreateCircle = new Runnable() {
        @Override
        public void run() {
            if (mIsRunning) {
                newCircle();
                postDelayed(mCreateCircle, mSpeed);
            }
        }
    };

    private void newCircle() {
        long currentTime = System.currentTimeMillis();
        if (currentTime - mLastCreateTime < mSpeed) {
            return;
        }
        Circle circle = new Circle();
        mCircleList.add(circle);
        invalidate();
        mLastCreateTime = currentTime;
    }

    private class Circle {
        private long mCreateTime;

        public Circle() {
            this.mCreateTime = System.currentTimeMillis();
        }

        public int getAlpha() {
            float percent = (System.currentTimeMillis() - mCreateTime) * 1.0f / mDuration;
            return (int) ((1.0f - mInterpolator.getInterpolation(percent)) * 255);
        }

        public float getCurrentRadius() {
            float percent = (System.currentTimeMillis() - mCreateTime) * 1.0f / mDuration;
            return mInitialRadius + mInterpolator.getInterpolation(percent) * (mMaxRadius - mInitialRadius);
        }
    }

    public void setInterpolator(Interpolator interpolator) {
        mInterpolator = interpolator;
        if (mInterpolator == null) {
            mInterpolator = new LinearInterpolator();
        }
    }

    /**
     * 开始
     */
    public void start() {
        if (!mIsRunning) {
            mIsRunning = true;
            mCreateCircle.run();
        }
    }

    /**
     * 停止
     */
    public void stop() {
        mIsRunning = false;
    }

}
